#include<reg52.h>
sfr P3M0=0xB2;
sfr P3M1=0xB1;

#define uint unsigned int
#define uchar unsigned char

sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
sbit bell=P3^7;

signed char hour,year,bell_hour,min,sec,bell_min,bell_sec;
uchar numdu,numwe,shi,ge,mon,day;
uint tt,tran,key_times,key_down,tran_bell;
uint count30s,count1s,count500ms,count100ms,count400ms,flag30s,flag1s,flag500ms,flag100ms,flag400ms;

uchar code table[]={0Xfb,0xfd,0xdf,0xef,0xf7,0x7f,0xfe,0xbf,0xff};
uchar code tabledu[]={0X41,0xdd,0xe0,0xc8,0x5c,0x4a,0x42,0xd9,0x40,0x48,0xff};
uchar code tablewe[]={0xdf,0xef,0xf7,0xfe,0xfd,0Xfb,0xcf,0xf6,0xf9};

void delay(uint z)
{
	uint x,y;
	for(x=z;x>0;x--)
		for(y=100;y>0;y--);
}
void init()
{
	TMOD=0x11;
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	EA=1;
	ET0=1;
	TR0=1;
	TH1=(65536-5000)/256;
	TL1=(65536-5000)%256;
	ET1=1;
	TR1=0;

	flag1s=0;
	flag500ms=0;
	flag400ms=0;
	flag100ms=0;

	numdu=0;
	numwe=0;
	shi=0;
	ge=0;
	tran=1;
	key_times=0;
	key_down=0;
	tran_bell=0;

	year=14;
	mon=5;
	day=16;
	hour=20;
	min=25;
	sec=0;

	bell_hour=0;
	bell_min=0;
	bell_sec=0;
}
void BELL()
{
	P3M0|=0x80;
	bell=1;
} 
void display_year()
{
		shi=year/10;
		ge=year%10;
		P0=tabledu[shi];
		P2=tablewe[0];
		delay(30);
	
		P0=tabledu[ge]&0xbf;
		P2=tablewe[1];
		delay(30);
}
void display_mon()
{	
		shi=mon/10;
		ge=mon%10;
		P0=tabledu[shi];
		P2=tablewe[2];
		delay(30);
	
		P0=tabledu[ge]&0xbf;
		P2=tablewe[3];
		delay(30);
}
void display_day()
{	
		shi=day/10;
		ge=day%10;
		P0=tabledu[shi];
		P2=tablewe[4];
		delay(30);
	
		P0=tabledu[ge];
		P2=tablewe[5];
		delay(30);
}
void display_hour(signed char hour)
{
		shi=hour/10;
		ge=hour%10;
		P0=tabledu[shi];
		P2=tablewe[0];
		delay(30);
	
		P0=tabledu[ge]&0xbf;
		P2=tablewe[1];
		delay(30);
}
void display_min(signed char min)
{	
		shi=min/10;
		ge=min%10;
		P0=tabledu[shi];
		P2=tablewe[2];
		delay(30);
	
		P0=tabledu[ge]&0xbf;
		P2=tablewe[3];
		delay(30);
}
void display_sec(signed char sec)
{	
		shi=sec/10;
		ge=sec%10;
		P0=tabledu[shi];
		P2=tablewe[4];
		delay(30);
	
		P0=tabledu[ge];
		P2=tablewe[5];
		delay(30);
}
void display()
{
	if(tran==1)
	{
		display_year();
		display_mon();
		display_day();
	}
	if(tran==2)
	{
		display_hour(hour);
		display_min(min);
		display_sec(sec);
	}
	if(tran==3)
	{
		display_hour(bell_hour);
		display_min(bell_min);
		display_sec(bell_sec);
	}
	if(key_times==1)
	{
		TR1=1;
		tran=0;
		if(flag500ms==1)
		{	
			display_year();
			display_mon();
			display_day();
		}
		if(flag1s==1)
		{	
			flag500ms=0;
			flag1s=0;
			TR1=0;
		}
		if(flag500ms!=1)
		{	
			P0=tabledu[0xff];
			P2=tablewe[7];
			display_mon();
			display_day();
		}
	}
	if(key_times==2)
	{
		TR1=1;
		if(flag500ms==1)
		{
			display_year();
			display_mon();
			display_day();
		}
		if(flag1s==1)
		{	
			flag500ms=0;
			flag1s=0;
			TR1=0;
		}
		if(flag500ms!=1)
		{		
			display_year();
			P0=tabledu[0xff];
			P2=tablewe[8];
			display_day();
		}
	}
	if(key_times==3)
	{
		TR1=1;
		if(flag500ms==1)
		{	
			display_year();
			display_mon();
			display_day();
		}
		if(flag1s==1)
		{	
			flag500ms=0;
			flag1s=0;
			TR1=0;
		}
		if(flag500ms!=1)
		{	

			display_year();
			display_mon();
			P0=tabledu[0xff];
			P2=tablewe[9];
		}
	}
	if(key_times==4)
	{
		TR1=1;
		tran=0;
		if(flag500ms==1)
		{	
			if(tran_bell==0)
			{
				display_hour(hour);
				display_min(min);
				display_sec(sec);
			}
			if(tran_bell==1)
			{
				display_hour(bell_hour);
				display_min(bell_min);
				display_sec(bell_sec);
			}
		}
		if(flag1s==1)
		{	
			flag500ms=0;
			flag1s=0;
			TR1=0;
		}
		if(flag500ms!=1)
		{		
 	   	if(tran_bell==0)
			{
				P0=tabledu[0xff];
				P2=tablewe[7];
				display_min(min);
				display_sec(sec);
			}
			if(tran_bell==1)
			{
				P0=tabledu[0xff];
				P2=tablewe[7];
				display_min(bell_min);
				display_sec(bell_sec);
			}
		}
	}
	if(key_times==5)
	{
		TR1=1;
		if(flag500ms==1)
		{	
			if(tran_bell==0)
			{
				display_hour(hour);
				display_min(min);
				display_sec(sec);
			}
			if(tran_bell==1)
			{
				display_hour(bell_hour);
				display_min(bell_min);
				display_sec(bell_sec);
			}
		}
		if(flag1s==1)
		{	
			flag500ms=0;
			flag1s=0;
			TR1=0;
		}
		if(flag500ms!=1)
		{
			if(tran_bell==0)
			{
				display_hour(hour);
				P0=tabledu[0xff];
				P2=tablewe[7];
				display_sec(sec);
			}
			if(tran_bell==1)
			{
				display_hour(bell_hour);
				P0=tabledu[0xff];
				P2=tablewe[7];
				display_sec(bell_sec);
			}
		}
	}
	if(key_times==6)
	{
		TR1=1;
		if(flag500ms==1)
		{	
			if(tran_bell==0)
			{
				display_hour(hour);
				display_min(min);
				display_sec(sec);
			}
			if(tran_bell==1)
			{
				display_hour(bell_hour);
				display_min(bell_min);
				display_sec(bell_sec);
			}
		}
		if(flag1s==1)
		{	
			flag500ms=0;
			flag1s=0;
			TR1=0;
		}
		if(flag500ms!=1)
		{
			if(tran_bell==0)
			{
				display_hour(hour);
				display_min(min);
				P0=tabledu[0xff];
				P2=tablewe[7];
			}
			if(tran_bell==1)
			{
				display_hour(bell_hour);
				display_min(bell_min);
				P0=tabledu[0xff];
				P2=tablewe[7];
			}
		}
	}	
}
void key()
{
	uint key_down,key_daley,trg,cont,cont1,temp;

	if(key1==0)
	{
		delay(10);
		if(key1==0)
		{
			bell=0;
			if(key_times!=0)
			{  
				if(key_times==1)
				{
					year++;
					if(year==100)
						year=0;
				}
				if(key_times==2)
				{
					mon++;
					if(mon==13)
						mon=1;
				}
				if(key_times==3)
				{
						day++;
						if(day==31)
							day=1;
				} 
				if(key_times==4)
				{
					if(tran_bell==0)
					{
						hour++;
						if(hour==24)
							hour=0;
					}
					if(tran_bell==1)
					{
						bell_hour++;
						if(bell_hour==24)
							bell_hour=0;				
					}
				}	
				if(key_times==5)
				{
					if(tran_bell==0)
					{
						min++;
						if(min==60)
							min=0;
					}
					if(tran_bell==1)
					{
						bell_min++;
						if(bell_min==60)
							bell_min=0;
					}
				}	
				if(key_times==6)
				{
					if(tran_bell==0)
					{
						sec++;
						if(sec==60)
							sec=0;
					}
					if(tran_bell==1)
					{
						bell_sec++;
						if(bell_sec==60)
							bell_sec=0;
					}
				}   
				while(!key1)
				display();
			}
		}
	}
	if(key2==0)
	{
		delay(10);
		if(key2==0)
		{	
			bell=0;
			if(key_times!=0)
			{
				key_daley++;
				if(key_daley>200)
				{
					TR0=1;	
					key_daley=0;
					key_times=0;
					tran_bell=0;
					tran=2;
					display();
				}
				temp=!key2;
				trg=temp*(temp^cont1);
				cont1=temp;			
				if(trg&temp)
				{
					key_times++;
					if(key_times==4)
					{
						tran=2;
						display();
					}
					if(key_times==7)
					{
						TR0=1;
						key_times=0;
						tran=2;
						display();
						tran_bell=0;
					}
				}
			}
		}
	}
	if(key2==1)
	{
		cont1=0;
	}
	if(key3==0)
	{
		delay(4);
		if(key3==0)
		{
			bell=0;
			key_daley++;
			temp=!key3;
			trg=temp*(temp^cont);
			cont=temp;			
			if(trg&temp&tran_bell!=1)
			{
				tran++;
				key_down++;
				TR1=1;
				if(tran==2)
				{
					display();
				}
				if(tran==3)
				{
					tran=1;	
				}
			}
			if(key_daley>200)
			{	
				TR0=0;
				key_daley=0;
				key_times=4;
				tran_bell=1;
				tran=3;
				display();
			}
		}		
	}
	if(flag100ms==1)
	{
		if(key_down==2)
		{	 	
			flag100ms=0;
			key_down=0;
			TR0=0;
			TR1=0;
	//		TH1=(65536-5000)/256;
	//		TL1=(65536-5000)%256;
			key_times=1;
		}
	}
	if(flag400ms==1&tran!=0)
	{
		flag400ms=0;
		key_down=0;
		TR1=0;
	//	TH1=(65536-5000)/256;
	//	TL1=(65536-5000)%256;
	} 	
	if(key3==1)
	{
		cont=0;
	}
	if(key4==0)
	{
		delay(10);
		if(key4==0)
		{
			bell=0;
			if(key_times!=0)
			{
				if(key_times==1)
				{
					year--;
					if(year==-1)
						year=99;
				}
				if(key_times==2)
				{
					mon--;
					if(mon==0)
						mon=12;
				}
				if(key_times==3)
				{
					day--;
					if(day==0)
						day=30;
				} 
				if(key_times==4)
				{
					if(tran_bell==0)
					{
						hour--;
						if(hour==-1)
							hour=23;
					}
					if(tran_bell==1)
					{
						bell_hour--;
						if(bell_hour==-1)
							bell_hour=23;				
					}
				}	
				if(key_times==5)
				{
					if(tran_bell==0)
					{
						min--;
						if(min==-1)
							min=59;
					}
					if(tran_bell==1)
					{
						bell_min--;
						if(bell_min==-1)
							bell_min=59;
					}
				}	
				if(key_times==6)
				{
					if(tran_bell==0)
					{
						sec--;
						if(sec==-1)
							sec=59;
					}
					if(tran_bell==1)
					{
						bell_sec--;
						if(bell_sec==-1)
							bell_sec=59;
					}
				}
				while(!key4)
				display();
			}
		}
	}
		
}
void time()
{
	if(tt==20)
	{
		tt=0;
		sec++;
		if(sec==60)
		{
			sec=0;
			min++;
			if(min==60)
			{
				min=0;
				hour++;
				if(hour==24)
				{
					hour=0;
					day++;
					if(day==31)
					{
						day=1;
						mon++;
						if(mon==13)
						{
							mon=1;
							year++;
							if(year==99)
								year=0;
						}
					}
				}
			}
		}
	}

}
void judge()	
{
	if(hour==bell_hour&min==bell_min&sec==bell_sec&tran_bell!=1)
	{
		BELL();
/*		TR1=1;
		if(flag30s==1)
		{
			flag30s=0;
			TR1=0;
			bell=0;
		}	*/
	}
}
void main()
{
	init();
	while(1)
	{	
		key();
		time();
		display();
		judge();
	}

}
void count() interrupt 1
{
	TH0=(65536-50000)/256;
	TL0=(65536-50000)%256;
	tt++;
}
void count1() interrupt 3
{
	TH1=(65536-5000)/256;
	TL1=(65536-5000)%256;
	count100ms++;
	if(count100ms>20)
	{
		count100ms=0;
		flag100ms=1;
	}	
	count400ms++;
	if(count400ms>80)
	{
		count400ms=0;
		flag400ms=1;
	}
	count500ms++;
	if(count500ms>100)
	{
		count500ms=0;
		flag500ms=1;
	}
	count1s++;
	if(count1s>200)
	{
		count1s=0;
		flag1s=1;
	}
	if(count30s>600)
	{
		count30s=0;
		flag30s=1;
	}
}
